JVM系列(三) JVM垃圾判断及强引用关系

您所在的位置:网站首页 allocation failure scavenge JVM系列(三) JVM垃圾判断及强引用关系

JVM系列(三) JVM垃圾判断及强引用关系

2023-03-23 01:37| 来源: 网络整理| 查看: 265

1.判断垃圾对象

如何判断该对象是垃圾,或者该对象要被回收?

引用计数法 在对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就 +1当引用失效时,计数器值就-1 ;任何时刻计数器为 0 的对象就是没人用的,那么就要被回收优点是原理简单,效率高问题是无法解决循环引用的问题A->B,B->A, 对于A,B两个对象,计数器全都是1,其实两个对象再无其他引用了,是要被回收的,但是计数器法就无法解决 可达性分析法 以GC Roots的根对象作为起始节点集从根节点开始,根据引用关系向下搜索,搜索所走过的路径称为如果GC Roots 和某个对象没有任何引用链,也就是该对象不可达,该对象就是没人用的,就要被回收 2.JVM的引用关系

设置JVM参数

设置 最大内存 30M默认 young:old 是 1:2所以 年轻到 10M, 老年代 20M年轻代默认 eden/from/to 8:1:1年轻代可用的 应该在 8+1=9M左右老年代 应该在 20M左右 -verbose:gc -Xmx30M -XX:+PrintGC -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError

配置JVM参数

image.png

3 强引用

平时大多的新建的对象都是强引用,程序代码之中普遍存在的引用赋值,无论任何情况下,只要强引用关系还存在,垃圾收集器就永远不会回收掉被引用的对象

如果所有的GC ROOTS对象都没有与某个对象有强引用路径,那么这个对象就可以被垃圾回收的

Object obj=new Object() 3.1 强引用测试

我们来测试一下强引用

public class JvmTest { static class MyBigObj { // 创建5M大小的字节数组 private byte[] bytes = new byte[1024*1024*5]; } public static void main(String[] args) throws Exception { //测试强连接 strongTest(); } public static void strongTest() throws Exception{ //每次都创建 不同的对象, 强连接, 即使执行gc 也不会被回收, 再次创建OOM for (int i = 0; i < 6; i++) { MyBigObj big = new MyBigObj(); System.out.println("========="+i); } } } 3.2 启动程序

查看 自己JVM使用的是哪种垃圾回收方式

java -XX:+PrintCommandLineFlags -version

查看结果

-XX:InitialHeapSize=268435456 -XX:MaxHeapSize=4294967296 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC java version "1.8.0_202" Java(TM) SE Runtime Environment (build 1.8.0_202-b08) Java HotSpot(TM) 64-Bit Server VM (build 25.202-b08, mixed mode) -XX:+UseParallelGC 使用并行收集器并行收集器就是 新生代(Parallel Scavenge),老年代(Ps MarkSweep)组合打印的 新生代 PSYoungGen打印的 老年代 ParOldGen

运行方法, 我们看下打印日志, 是不是使用的 UseParallelGC并行收集器

=========0 =========1 =========2 [GC (Allocation Failure) [PSYoungGen: 7062K->1008K(9216K)] 22422K->16916K(29696K), 0.0022281 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] =========3 [GC (Allocation Failure) [PSYoungGen: 6291K->1008K(9216K)] 22200K->16972K(29696K), 0.0018994 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] =========4 [GC (Allocation Failure) [PSYoungGen: 6290K->1008K(9216K)] 22254K->16988K(29696K), 0.0016448 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] =========5 Heap PSYoungGen total 9216K, used 6453K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000) eden space 8192K, 66% used [0x00000007bf600000,0x00000007bfb51528,0x00000007bfe00000) from space 1024K, 98% used [0x00000007bfe00000,0x00000007bfefc198,0x00000007bff00000) to space 1024K, 0% used [0x00000007bff00000,0x00000007bff00000,0x00000007c0000000) ParOldGen total 20480K, used 15980K [0x00000007be200000, 0x00000007bf600000, 0x00000007bf600000) object space 20480K, 78% used [0x00000007be200000,0x00000007bf19b198,0x00000007bf600000) Metaspace used 4698K, capacity 5068K, committed 5248K, reserved 1056768K class space used 522K, capacity 564K, committed 640K, reserved 1048576K 3.3 gc日志分析

下面我们分析下日志

PSYoungGen total 9216K 年轻代的确是 9M, 可用的 占年轻代 90%eden space 8192K eden区是 8M 满足 8:1:1 eden/from/tofrom space 1024K from区 1Mto space 1024K to区 1MParOldGen total 20480K 老年代的确是 20M, 与年轻代比例是 1:2 young:oldMetaspace used 4728K, capacity 5068K 元空间可用 5M 用了4M

然后分析下YoungGC和FullGC

第一次 5M的obj 被成功 放到9M的 young区, 剩余第二次 5M的obj 被成功 放到9M的 eden区 没问题第三次 5M的obj 再被放入 eden区时候,不够了, 使用了 7092, 发生YoungGC, gc后剩余 1008k第四次可以继续放, 一次类推, 放一次,YoungGC后清理出来部分空间继续放,继续清理 直至结束 3.4 强引用存在 回收不了OOM

把逻辑如下修改, 用list来存储big对象, 这样就不会被回收掉

public static void strongTest() throws Exception{ //每次都创建 不同的对象, 强连接, 即使执行gc 也不会被回收, 再次创建OOM List list = new ArrayList(); for (int i = 0; i < 6; i++) { MyBigObj big = new MyBigObj(); list.add(big); System.out.println("========="+i); } }

多次执行后 看下结果

Full GC [PSYoungGen: 6292K->6053K(9216K)] eden区无法回收Full GC [ParOldGen: 15945K->15625K(20480K)] 22238K->21679K(29696K) 老年代也无法回收导致 java.lang.OutOfMemoryError: Java heap space 内存溢出 =========0 =========1 =========2 [GC (Allocation Failure) [PSYoungGen: 7062K->1008K(9216K)] 22422K->16922K(29696K), 0.0023415 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] =========3 [GC (Allocation Failure) --[PSYoungGen: 6292K->6292K(9216K)] 22206K->22238K(29696K), 0.0021786 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] [Full GC (Ergonomics) [PSYoungGen: 6292K->6053K(9216K)] [ParOldGen: 15945K->15625K(20480K)] 22238K->21679K(29696K), [Metaspace: 4692K->4692K(1056768K)], 0.0060295 secs] [Times: user=0.02 sys=0.00, real=0.00 secs] [GC (Allocation Failure) --[PSYoungGen: 6053K->6053K(9216K)] 21679K->21703K(29696K), 0.0019607 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] [Full GC (Allocation Failure) [PSYoungGen: 6053K->5966K(9216K)] [ParOldGen: 15649K->15638K(20480K)] 21703K->21604K(29696K), [Metaspace: 4692K->4692K(1056768K)], 0.0058404 secs] [Times: user=0.02 sys=0.00, real=0.00 secs] java.lang.OutOfMemoryError: Java heap space

这就是强引用, 如果内存一直存在无法回收, 就会出现OOM



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3